﻿namespace PushNotifications.WinRT
{
    using System;

    public interface INotificationMessage
    {
        NotificationType Type { get; }

        CachePolicy CachePolicy { get; }

        bool RquestForStatus { get; }

        int? TTL { get; }

        string Tag { get; }

        string GetContent();
    }

    public enum NotificationType
    {
        Tile,
        Badge,
        Toast,
        Raw
    }

    public static class NotificationTypeKeys
    {
        public const string TILE = "wns/tile";
        public const string BADGE = "wns/badge";
        public const string TOAST = "wns/toast";
        public const string RAW = "wns/raw";

        public static string GetKey(this NotificationType type)
        {
            switch (type)
            {
                case NotificationType.Tile:
                    return NotificationTypeKeys.TILE;
                    break;
                case NotificationType.Badge:
                    return NotificationTypeKeys.BADGE;
                    break;
                case NotificationType.Toast:
                    return NotificationTypeKeys.TOAST;
                    break;
                case NotificationType.Raw:
                    return NotificationTypeKeys.RAW;
                    break;
                default:
                    throw new Exception();
            }
        }

        public static NotificationType GetNotificationType(this string type)
        {
            switch (type)
            {
                
                case NotificationTypeKeys.TILE:
                    return NotificationType.Tile;
                    break;
                
                case NotificationTypeKeys.BADGE:
                    return NotificationType.Badge;
                    break;
                
                case NotificationTypeKeys.TOAST:
                    return NotificationType.Toast;
                    break;
                case NotificationTypeKeys.RAW:
                    return NotificationType.Raw;
                    break;
                default:
                    throw new Exception();
            }
        }
    }

    public enum CachePolicy
    {
        Cache,

        NoCache
    }

    public static class CachePolicyKeys
    {
        public const string CACHE = "cache";

        public const string NOCACHE = "no-cache";

        public static string GetKey(this CachePolicy type)
        {
            switch (type)
            {
                case CachePolicy.Cache:
                    return CachePolicyKeys.CACHE;
                    break;
                case CachePolicy.NoCache:
                    return CachePolicyKeys.NOCACHE;
                    break;
                default:
                    throw new Exception();
            }
        }

        public static CachePolicy GetCachePolicy(this string type)
        {
            switch (type)
            {

                case CachePolicyKeys.CACHE:
                    return CachePolicy.Cache;
                    break;

                case CachePolicyKeys.NOCACHE:
                    return CachePolicy.NoCache;
                    break;
                default:
                    throw new Exception();
            }
        }
    }

    public class NotificationResult
    {
        public ServiceResult ServiceResult { get; set; }
        
        public string DeviceConnectionStatus { get; set; }

        public string ErrorDescription { get; set; }

        public string MsgId { get; set; }

        public string NotificationStatus { get; set; }
    }

    public enum ServiceResult
    {
        Ok,

        BadRequest,

        UnAutorized,

        Forbidden,

        NotFound,

        MethodNotAllowed,

        NotAcceptable,

        Gone,

        RequestEntityTooLarge,

        InternalServerError,

        ServiceUnavailable
    }

    public enum DeviceConnectionStatus
    {
        Connected,

        Disconnected,

        TempDisconnected
    }

    public static class DeviceConnectionStatusKeys
    {
        public const string CONNECTED = "connected";

        public const string DISCONNECTED = "disconnected";

        public const string TEMPDISCONNECTED = "tempdisconnected";

        public static string GetKey(this DeviceConnectionStatus type)
        {
            switch (type)
            {
                case DeviceConnectionStatus.Connected:
                    return DeviceConnectionStatusKeys.CONNECTED;
                    break;
                case DeviceConnectionStatus.Disconnected:
                    return DeviceConnectionStatusKeys.DISCONNECTED;
                    break;
                case DeviceConnectionStatus.TempDisconnected:
                    return DeviceConnectionStatusKeys.TEMPDISCONNECTED;
                    break;
               
                default:
                    throw new Exception();
            }
        }

        public static DeviceConnectionStatus GetDeviceConnectionStatus(this string type)
        {
            switch (type)
            {

                case DeviceConnectionStatusKeys.CONNECTED:
                    return DeviceConnectionStatus.Connected;
                    break;

                case DeviceConnectionStatusKeys.DISCONNECTED:
                    return DeviceConnectionStatus.Disconnected;
                    break;

                case DeviceConnectionStatusKeys.TEMPDISCONNECTED:
                    return DeviceConnectionStatus.TempDisconnected;
                    break;
                default:
                    throw new Exception();
            }
        }
    }

    public enum NotificationStatus
    {
        Recieved,

        Dropped,

        ChannelThrottled
    }

    public static class NotificationStatusKeys
    {
        public const string RECEIVED = "received";

        public const string DROPPED = "dropped";

        public const string CHANNELTHROTTLED = "channelthrottled";

        public static string GetKey(this NotificationStatus type)
        {
            switch (type)
            {
                case NotificationStatus.Recieved:
                    return NotificationStatusKeys.RECEIVED;
                    break;
                case NotificationStatus.Dropped:
                    return NotificationStatusKeys.DROPPED;
                    break;
                case NotificationStatus.ChannelThrottled:
                    return NotificationStatusKeys.CHANNELTHROTTLED;
                    break;

                default:
                    throw new Exception();
            }
        }

        public static NotificationStatus GetNotificationStatus(this string type)
        {
            switch (type)
            {

                case NotificationStatusKeys.RECEIVED:
                    return NotificationStatus.Recieved;
                    break;

                case NotificationStatusKeys.DROPPED:
                    return NotificationStatus.Dropped;
                    break;

                case NotificationStatusKeys.CHANNELTHROTTLED:
                    return NotificationStatus.ChannelThrottled;
                    break;
                default:
                    throw new Exception();
            }
        }
    }
}
